package com.admin.service.impl;

import com.admin.persistence.sys.entity.*;
import com.admin.persistence.sys.mapper.*;
import com.admin.service.SysRoleService;
import com.admin.service.vo.SysRole;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.admin.common.CommonUtils;
import com.admin.common.biz.ModelUseStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Service
public class SysRoleServiceImp implements SysRoleService {

    RoleMapper roleMapper;

    RoleMenuMapper roleMenuMapper;

    RoleJurisdtionMapper roleJurisdtionMapper;

    MenuMapper menuMapper;

    JurisdtionMapper jurisdtionMapper;

    UserMapper userMapper;

    UserRoleMapper userRoleMapper;

    GroupRoleMapper groupRoleMapper;

    UserGroupMapper userGroupMapper;

    @Override
    public SysRole createSysRole(SysRole sysRole) {
        Role role = sysRole.getRole();
        if (!canUseRoleName(role.getName())) return null;
        role.setId(CommonUtils.createId());
        roleMapper.insert(role);
        List<Menu> menus = sysRole.getMenus();
        List<Jurisdtion> jurisdtions = sysRole.getJurisdtions();
        if (!CollectionUtils.isEmpty(menus)) {
            menus.stream().filter(cur -> {
                return cur != null && !StringUtils.isEmpty(cur.getId());
            }).forEach(cur -> {
                roleMenuMapper.insert(new RoleMenu(CommonUtils.createId(), role.getId(), cur.getId()));
            });
        }

        if (!CollectionUtils.isEmpty(jurisdtions)) {
            jurisdtions.stream().filter(cur -> {
                return cur != null && !StringUtils.isEmpty(cur.getId());
            }).forEach(cur -> {
                roleJurisdtionMapper.insert(new RoleJurisdtion(CommonUtils.createId(), role.getId(), cur.getId()));
            });
        }
        return sysRole;
    }

    @Override
    public int saveSysRole(SysRole sysRole) {
        Role role = sysRole.getRole();
        if (roleMapper.selectById(role.getId()) != null) {
            return roleMapper.updateById(role);
        } else {
            role.setId(CommonUtils.createId());
            return roleMapper.insert(role);
        }

    }

    @Override
    public int edtionSysRole(SysRole sysRole) {
        Role role = sysRole.getRole();
        return roleMapper.updateById(role);
    }

    @Override
    public int removeSysRole(SysRole sysRole) {
        Role role = sysRole.getRole();
        role.setStatus(ModelUseStatus.REMVOE.value);
        return roleMapper.updateById(role);
    }

    @Override
    public List<SysRole> queryById(String... id) {
        List<SysRole> result = new ArrayList<>();
        if (id.getClass().isArray()) {
            Optional.ofNullable(id).ifPresent(cur -> {
                List<Role> roles = null;
                List<Jurisdtion> jurisdtions = null;
                List<Menu> menus = null;
                if (cur.getClass().isArray()) {
                    roles = roleMapper.selectBatchIds(Arrays.asList(id));
                } else {
                    roles = new ArrayList<Role>();
                    roles.add(roleMapper.selectById(id));
                }
                Optional.ofNullable(roles).ifPresent(roleIndx -> {
                    roleIndx.stream().forEach(em -> {
                        result.add(new SysRole(em, menuMapper.queryByRole(em.getId()), jurisdtionMapper.queryByRole(em.getId())));
                    });
                });
            });
        }
        return result;
    }

    @Override
    public List<SysRole> queryAll() {
        List<SysRole> result = new ArrayList<SysRole>();
        List<Role> roles = roleMapper.selectList(null);
        Optional.ofNullable(roles).ifPresent(cur -> {
            cur.forEach(em -> {
                result.add(new SysRole(em, menuMapper.queryByRole(em.getId()), jurisdtionMapper.queryByRole(em.getId())));
            });
        });
        return result;
    }

    @Override
    public List<SysRole> queryByAccount(String account) {
        List<SysRole> result = new ArrayList<SysRole>();
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("ACCOUNT", account));
        List<UserGroup> usergroups = null;
        List<Role> roles = new ArrayList<Role>();
        if (user != null) {
            usergroups = userGroupMapper.queryByUser(user.getId());
            roles.addAll(roleMapper.queryByUser(user.getId()));
        }
        if (!CollectionUtils.isEmpty(usergroups)) {
            usergroups.stream().forEach(emGroup -> {
                List<Role> tempRoles = roleMapper.queryByUserGroup(emGroup.getId());
                if (!CollectionUtils.isEmpty(tempRoles)) {
                    roles.addAll(tempRoles);
                }
            });
        }
        roles.stream().map(cur -> {
            return cur.getId();
        }).forEach(curId -> {
            result.add(new SysRole(roleMapper.selectById(curId), menuMapper.queryByRole(curId),
                    jurisdtionMapper.queryByRole(curId)));
        });
        return result;
    }

    @Override
    public List<SysRole> queryByUserGroup(String userGroupId) {
        List<SysRole> results = new ArrayList<SysRole>();
        List<Role> roles = roleMapper.queryByUserGroup(userGroupId);
        if (!CollectionUtils.isEmpty(roles)) {
            roles.stream().forEach(em -> {
                results.add(new SysRole(em, menuMapper.queryByRole(em.getId()), jurisdtionMapper.queryByRole(em.getId())));
            });
        }
        return results;
    }

    @Override
    public boolean canRemove(String roleId) {

        return !CollectionUtils.isEmpty(userRoleMapper.selectList(new QueryWrapper<UserRole>().eq("ROLE_ID", roleId)))
                || !CollectionUtils.isEmpty(groupRoleMapper.selectList(new QueryWrapper<GroupRole>().eq("ROLE_ID", roleId)));
    }

    @Override
    public boolean canUseRoleName(String roleName) {
        return CollectionUtils.isEmpty(roleMapper.selectList(new QueryWrapper<Role>().eq("NAME", roleName)));
    }
}
